//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.eResearch.Execution
{
    using System;
    using System.Xml;

    /// <summary>
    /// Class for loading the WF xoml and setting the parameter values.
    /// </summary>
    internal class ParameterSetter
    {
        /// <summary>
        /// XOML Document instance.
        /// </summary>
        private XmlDocument xomlInstance = new XmlDocument();

        /// <summary>
        /// Constructor for the Class.
        /// </summary>
        /// <param name="xomlFileName">XOML Filename.</param>
        public ParameterSetter(string xomlFileName)
        {
            this.xomlInstance.Load(xomlFileName);
        }

        /// <summary>
        /// Get the total Activities count.
        /// </summary>
        /// <returns>Total Activities.</returns>
        public int GetActivityCount()
        {
            return this.GetTotalElementCount(this.xomlInstance.FirstChild);
        }

        /// <summary>
        /// Traverses the paramXml and assigns the parameter values 
        /// to the WF xoml.
        /// </summary>
        /// <param name="paramXml">Parameter XML.</param>
        /// <returns>Assigned or not.</returns>
        public int AssignVariableValues(XmlDocument paramXml)
        {
            foreach (XmlNode node in paramXml.ChildNodes[0].ChildNodes)
            {
                XmlNode xomlNode = this.GetXomlNode(this.xomlInstance, node.Attributes.GetNamedItem("Id").Value);
                if (null == xomlNode)
                {
                    Console.WriteLine("Parameters in the parameter xml are not present in the WF instance");
                    return -1;
                }

                foreach (XmlNode param in node)
                {
                    string paramName = param.Attributes.GetNamedItem("name").Value;
                    string paramValue = param.Attributes.GetNamedItem("value").Value;

                    XmlAttribute paramAttr = (XmlAttribute)xomlNode.Attributes.GetNamedItem(paramName);
                    if (null == paramAttr)
                    {
                        paramAttr = this.xomlInstance.CreateAttribute(paramName);
                        paramAttr.Value = paramValue;
                        xomlNode.Attributes.Append(paramAttr);
                    }
                    else
                    {
                        paramAttr.Value = paramValue;
                    }
                }
            }

            return 0;
        }

        /// <summary>
        /// Method for saving the WF to the specified file.
        /// </summary>
        /// <param name="fileName">Save the Workflow to specified filename.</param>
        /// <returns>Successfully Saved.</returns>
        public int SaveWF(string fileName)
        {
            if (null == this.xomlInstance)
            {
                return -1;
            }

            try
            {
                this.xomlInstance.Save(fileName);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return -1;
            }

            return 0;
        }

        /// <summary>
        /// Recursive method to find the total number of activities in a
        /// the current xoml.
        /// </summary>
        /// <param name="parentNode">Parent elemnt node.</param>
        /// <returns>Count of elements.</returns>
        public int GetTotalElementCount(XmlNode parentNode)
        {
            int elementCount = 0;
            if (parentNode.HasChildNodes)
            {
                foreach (XmlNode node in parentNode.ChildNodes)
                {
                    elementCount += this.GetTotalElementCount(node);
                }
            }

            elementCount += 1;
            return elementCount;
        }

        /// <summary>
        /// Recursive method to get the xoml node based on the id.
        /// </summary>
        /// <param name="parentNode">Parent node.</param>
        /// <param name="activityInstanceName">Instance of the activity.</param>
        /// <returns>XML Element node.</returns>
        private XmlNode GetXomlNode(XmlNode parentNode, string activityInstanceName)
        {
            if (parentNode.HasChildNodes)
            {
                foreach (XmlNode node in parentNode.ChildNodes)
                {
                    if (node.HasChildNodes)
                    {
                        XmlNode outNode = this.GetXomlNode(node, activityInstanceName);

                        if (null != outNode)
                        {
                            return outNode;
                        }
                    }

                    string actName;
                    if (null == node.Attributes.GetNamedItem("x:Name"))
                    {
                        actName = node.Attributes.GetNamedItem("Name").Value;
                    }
                    else
                    {
                        actName = node.Attributes.GetNamedItem("x:Name").Value;
                    }

                    if (activityInstanceName == actName)
                    {
                        return node;
                    }
                }
            }

            return null;
        }
    }
}*/
